<script setup>
	import { ref, onMounted, getCurrentInstance, watch, reactive } from 'vue';
	import request from '@/utils/request';
	const { proxy } = getCurrentInstance();
	import { useLeftNavStore } from '@/store/modules/leftNav';
	import contextMenu from '@/components/contextMenu/contextMenu.vue'

	const store = useLeftNavStore();
	const sub = store.$subscribe(() => {
		initLeftMenu();
	});

	const props = defineProps({
		title: {
			// 菜单标题
			type: String,
			default: () => '左侧菜单',
		},
		url: {
			type: String,
			default: () => '',
		},
		method: {
			type: String,
			default: () => 'post',
		},
		showKey: {
			// 菜单内列表显示文字的key
			type: String,
			default: () => '',
		},
		search: {
			// 是否开启搜索
			type: Boolean,
			default: () => false,
		},
		isTree: {
			// 是否开启树形结构
			type: Boolean,
			default: () => false,
		},
		showCheckbox: {
			// 是否显示树状的复选框
			type: Boolean,
			default: () => false,
		},
		radioLable: {
			//单选用来做判断的字段
			type: String,
			default: ''
		},
		height: {
			type: String,
			default: '',
		},
		localData: {
			//本地数据-优先使用
			type: Array,
			default: () => {
				return [];
			},
		},
		//是否初始化的时候返回一次点击事件
		isAutoClick: {
			type: Boolean,
			default: true,
		},
		
		//右键菜单
		contentMenuOpt: {
			type: Array,
			default: () => {
				return [];
			},
		},
		//是否添加 全部数据 选项
		isAll: {
			type: Boolean,
			default: true
		},
		allText: {
			type: String,
			default: '所有数据'
		}
	});

	watch(() => props.localData, (newVal) => {
		setData(newVal);
	}, { deep: true })

	const emit = defineEmits(['doneFun']);

	const leftItemRef = ref(null);
	const initLeftMenu = async () => {
		try {
			const res = await request({
				url: props.url,
				method: props.method,
			});
			setData(res.data);
		} catch (error) {}
	};

	let leftDictArr = ref([]);
	let leftDictArrInit = ref([]);	//备份初始化的数据，用作搜索还原
	
	function setData(res) {
		let treeList = [{
			id: '0',
			pId: null,
			spread: true,
		}]
		treeList[0][props.showKey] = props.allText
		
		if (props.isTree) {
			let tem_arr = res
			if(tem_arr?.length === 0) return
			let resStringify = JSON.stringify(res)
			
			if(resStringify?.indexOf('children') != -1) {
				treeList[0].children = tem_arr
			}else {
				treeList[0].children = proxy.$common.setTreeData(tem_arr)
			}
			
			leftDictArr.value = treeList
			leftDictArrInit.value = treeList
			
			if(props.isAutoClick && treeList.length > 0) onTreeItemClick(treeList[0]);
		} else {
			let resCopy = JSON.parse(JSON.stringify(res))
			if(props.isAll) {
				resCopy.unshift(treeList[0])
			}
			leftDictArr.value = resCopy;
			leftDictArrInit.value = resCopy
		}
		proxy.$nextTick(() => {
			if (leftItemRef.value && leftItemRef.value[0]) {
				// 默认选中第一个
				leftItemRef.value[0].click();
			}
		});
	}

	let leftActiveIndex = ref(0);
	const onLeftItemClick = (t, i) => {
		emit('doneFun', t);
		leftActiveIndex.value = i;
	};
	onMounted(() => {
		if (props.url) {
			initLeftMenu();	//使用接口请求
		}else {
			setData(props.localData);	//使用本地数据
		}
	});
	
	//搜索
	let searchKey = ref('');
	//点击搜索按钮
	const onSearch = () => {
		if(searchKey.value) {
			//搜索框有数据时
			leftDictArr.value = proxy.$common.multiFilterTree(leftDictArrInit.value, searchKey.value, props.showKey)
			console.log(leftDictArr.value)
		}else {
			//搜索框为空时
			leftDictArr.value = JSON.parse(JSON.stringify(leftDictArrInit.value))
		}
	};

	const onTreeItemClick = (node, checked) => {
		if (props.radioLable) {
			//如果是单选
			setSelectData(node)
		} else {
			emit('doneFun', node);
		}
	};
	const selectedKey = ref('0');
	const checkedKeys = ref([]) //开启多选后，选中的节点
	const checkedKeysOld = ref([]) //备份已选的字段
	const treeKey = ref(new Date().getTime())

	function checkChange(node, checked) {
		if (props.radioLable) {
			//开启单选
			setSelectData(node)
		}else {
			//多选-不做处理单独拿取checkedKeys
			// console.log(node, checked)
		}
	}

	//处理单选数据
	function setSelectData(node) {
		let item = {}
		if (props.radioLable) {
			//如果是单选
			if (node[props.radioLable]) {
				// 如果是选中，并且是最后一项
				checkedKeys.value = []
				checkedKeys.value.push(node.id)
				checkedKeysOld.value = JSON.parse(JSON.stringify(checkedKeys.value))
				item = node
			}
			if (!node[props.radioLable]) {
				//如果点击的不是最后的目标则不进行操作
				checkedKeys.value = JSON.parse(JSON.stringify(checkedKeysOld.value))
			}
			treeKey.value = new Date().getTime() //刷新树
		}
		
		emit('doneFun', item);
	}

	//右键菜单
	const contextMenuRef = ref(null)
	function contextmenu(e, data) {
		if(props.contentMenuOpt.length == 0) return
		contextMenuRef.value.useContextMenu(e, data)
	}
	
	defineExpose({
		leftDictArr,
		leftActiveIndex,
		checkedKeys,
	});
</script>
<template>
	<div id="site-tree-nav" class="leftnav" :style="`height: ${height}`">
		<div class="site-ul-nav">
			<div class="tree-title">{{ title }}</div>
			<div v-show="search" class="search padding-sm">
				<lay-input v-model="searchKey">
					<template #suffix>
						<button type="button" class="layui-btn layui-btn-primary suffix-btn" lay-filter="search" @click="onSearch">搜索</button>
					</template>
				</lay-input>
			</div>
			<!-- 右键菜单 -->
			<contextMenu ref="contextMenuRef" :contentMenuOpt="contentMenuOpt">
				<ul v-if="!isTree" id="ultype">
					<li ref="leftItemRef" v-for="(type, index) in leftDictArr" :class="{ active: index == leftActiveIndex }" :key="index" class="layui-nav-item" @click="() => onLeftItemClick(type, index)" @contextmenu.stop="contextmenu($event, type)">
						<a class="layui-nav-title" :class="type.cls ? type.cls : ''" href="javascript:void(0);">{{ props.showKey ? type[props.showKey] : index }}</a>
					</li>
				</ul>
				<div v-else>
					<lay-tree :key="treeKey" :data="leftDictArr" :showCheckbox="showCheckbox" :tail-node-icon="false" :onlyIconControl="true" @node-click="onTreeItemClick" @check-change="checkChange" v-model:checkedKeys="checkedKeys"
						v-model:selectedKey="selectedKey">
						<template #title="{ data }">
							<span @contextmenu.stop="contextmenu($event, data)" :class="data.cls ? data.cls : ''">{{ data[props.showKey] }}</span>
						</template>
					</lay-tree>
				</div>
				
				<div v-if="leftDictArr.length === 0" class="text-center text-gray text-lg" style="padding-top: 40px; width: 100%; overflow: hidden;">
					 <lay-empty></lay-empty>
				</div>
			</contextMenu>
		</div>
	</div>
</template>
<style lang="scss">
	/*==============================
    左侧栏,包含树形结构
=============================== */
	.leftnav,
	.ztreenav {
		width: 100%;
		/*max-width: 200px;*/
		background-color: #fff;
		border: 1px solid #ddd;
		padding: 3px;
		height: calc(100vh - 160px);
	}

	.leftnav .tree-title,
	.ztreenav .tree-title {
		height: 40px;
		line-height: 40px;
		background: #d9dee4;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		font-weight: 800;
		text-align: center;
		font-size: 1.1em;
	}

	.leftnav .site-ul-nav,
	.ztreenav .ztree-ul-nav {
		border-radius: 0;
	}

	.leftnav .site-ul-nav {
		width: 100%;
		height: 100%;
		overflow: auto;
		background: #eaedf1;
	}

	.leftnav .site-ul-nav li a {
		color: #666;
		height: 40px;
		line-height: 40px;
		display: block;
		padding: 0 20px;
		text-overflow: ellipsis;
		overflow: hidden;
		white-space: nowrap;
		margin: 3px 0;
	}

	.leftnav .site-ul-nav li.active>a,
	.leftnav .site-ul-nav li a:hover {
		background-color: #dae6fa;
		border-left: 2px solid #e96d25;
		color: #e96d25 !important;
	}

	.leftnav .layui-checkbox {
		padding-bottom: 0 !important;
	}
</style>